package common.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

import common.dao.IBaseDao;
import common.util.DbUtil;
import common.util.PageInfoUtil;

public abstract class BaseDaoImpl<T> implements IBaseDao<T>
{
	/***
	 * 执行sql语句
	 * 
	 * @param sql        SQL语句
	 * @param paramsList
	 * @return
	 */
	protected int excuteSql(String sql, List<Object> paramsList)
	{
		System.out.println("sql===" + sql);
		System.out.println("paramsList==" + paramsList);
		int res = 0;
		/* 标准的jdbc */
		DbUtil dbUtil = DbUtil.getInstance();
		/* 获取链接 */
		Connection connection = dbUtil.getConnection();
		PreparedStatement ps = null;
		ResultSet rs = null;
		try
		{
			/* 获取sql语句 */
			ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
			/* 为占位符赋值 */
			for (int i = 0; i < paramsList.size(); i++)
			{
				ps.setObject(i + 1, paramsList.get(i));
			}
			/* 执行sql语句 */
			res = ps.executeUpdate();
			/* 取主键 */
			rs = ps.getGeneratedKeys();
			if (rs.next())
			{
				int id = rs.getInt(1);
				/* List最后一个是主键 */
				paramsList.add(id);
			}
			return res;
		} catch (SQLException e)
		{
			e.printStackTrace();
		} finally
		{
			dbUtil.closeAll(connection, ps, rs);
		}
		return res;
	}

	/***
	 * 查询多条记录； 分页
	 * 
	 * @param pageInfoUtil sql语句
	 * @param sql
	 * @param paramsList   条件
	 * @param cla
	 * @return
	 */
	protected List<T> findListSql(PageInfoUtil pageInfoUtil, String sql, List<Object> paramsList, Class cla)
	{
		System.out.println("sql===" + sql);
		System.out.println("paramsList==" + paramsList);
		List<T> resultList = new ArrayList<T>();
		/* 标准的jdbc */
		DbUtil dbUtil = DbUtil.getInstance();
		/* 获取链接 */
		Connection connection = dbUtil.getConnection();
		PreparedStatement ps = null;
		ResultSet rs = null;
		try
		{
			/* 计算总条数数开始 */
			String countSql = "select count(*) " + sql.substring(sql.indexOf("from"), sql.length());
			System.out.println("=sql===>" + countSql);
			System.out.println("=参数===>" + paramsList);
			/* 获取sql语句 */
			ps = connection.prepareStatement(countSql, Statement.RETURN_GENERATED_KEYS);
			/* 为占位符赋值 */
			for (int i = 0; i < paramsList.size(); i++)
			{
				ps.setObject(i + 1, paramsList.get(i));
			}
			rs = ps.executeQuery() ; 
			/* 执行SQL语句 */
			if (rs.next())
			{
				int totalRecord = rs.getInt(1);
				pageInfoUtil.setTotalRecord(totalRecord);
			}
			rs.close();
			ps.close();

			sql = sql + " limit ?,?";
			paramsList.add(pageInfoUtil.getCurrentRecord());
			paramsList.add(pageInfoUtil.getPageSize());

			ps = connection.prepareStatement(sql.toString(), Statement.RETURN_GENERATED_KEYS);
			/* 为占位符赋值 */
			for (int i = 0; i < paramsList.size(); i++)
			{
				ps.setObject(i + 1, paramsList.get(i));
			}
			/* 执行sql语句 */
			rs = ps.executeQuery();
			while (rs.next())
			{
				T role = this.converFromRs(rs, cla);

				resultList.add(role);
			}
		} catch (SQLException e)
		{
			e.printStackTrace();
		} finally
		{
			dbUtil.closeAll(connection, ps, rs);
		}
		return resultList;
	}

	/***
	 * 查询多条不分页
	 * 
	 * @param sql        SQL 语句
	 * @param paramsList 条件
	 * @param cla
	 * @return
	 */
	protected List<T> findListSql(String sql, List<Object> paramsList, Class cla)
	{
		System.out.println("paramsList==" + paramsList);
		List<T> resultList = new ArrayList<T>();
		/* 标准的jdbc */
		DbUtil dbUtil = DbUtil.getInstance();
		/* 获取链接 */
		Connection connection = dbUtil.getConnection();
		PreparedStatement ps = null;
		ResultSet rs = null;
		try
		{
			System.out.println("=sql===>" + sql);
			System.out.println("=参数===>" + paramsList);
			/* 获取sql语句 */
			ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
			/* 为占位符赋值 */
			for (int i = 0; i < paramsList.size(); i++)
			{
				ps.setObject(i + 1, paramsList.get(i));
			}
			/* 执行sql语句 */
			rs = ps.executeQuery();
			while (rs.next())
			{
				T t = this.converFromRs(rs, cla);

				resultList.add(t);
			}
		} catch (SQLException e)
		{
			e.printStackTrace();
		} finally
		{
			dbUtil.closeAll(connection, ps, rs);
		}
		return resultList;
	}

	/***
	 * 查询一条记录
	 * 
	 * @param sql
	 * @param paramsList
	 * @param cla
	 * @return
	 */
	protected T findOneSql(String sql, List<Object> paramsList, Class cla)
	{
		System.out.println("sql===" + sql);
		System.out.println("paramsList==" + paramsList);
		/* 标准的jdbc */
		DbUtil dbUtil = DbUtil.getInstance();
		/* 获取链接 */
		Connection connection = dbUtil.getConnection();
		PreparedStatement ps = null;
		ResultSet rs = null;
		try
		{
			/* 获取sql语句 */
			ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
			/* 为占位符赋值 */
			for (int i = 0; i < paramsList.size(); i++)
			{
				ps.setObject(i + 1, paramsList.get(i));
			}
			/* 执行sql语句 */
			rs = ps.executeQuery();
			if (rs.next())
			{
				T t = converFromRs(rs, cla);
				return t;
			}
		} catch (SQLException e)
		{
			e.printStackTrace();
		} finally
		{
			dbUtil.closeAll(connection, ps, rs);
		}
		return null;
	}

	protected T converFromRs(ResultSet rs, Class cla) throws SQLException
	{
		// System.out.println("===convertFromRsToPojo======");
		/*
		 * 首先获取Class对象 最关键的是要先获取到Class对象 获取这个对象有三种方法
		 */
		/* 变量初始化 */
		T obj = null;
		try
		{
			/* 创建对象 */
			obj = (T) cla.newInstance();
		} catch (Exception e)
		{
			e.printStackTrace();
		}

		/* 获取所有的属性 */
		Field[] fileds = cla.getDeclaredFields();
		for (Field fieldTemp : fileds)
		{
			/* 获取属性的名字 */
			String fieldName = fieldTemp.getName();

			if (fieldName.endsWith("Str") || fieldName.endsWith("Obj")||fieldName.endsWith("List")||fieldName.endsWith("role")
				|| fieldName.endsWith("statusStr")|| fieldName.endsWith("sexStr")|| fieldName.endsWith("enumsMap")	)
			{
				continue;
			}
			
			
			/* 获取属性的值 */
			Object val = rs.getObject(fieldName);
			/*
			 * 通过反射获取pojo的set方法 set方法都是set属性名(属性名首字母大写)
			 * 
			 * 参数1:方法名 参数2;方法的参数是Class对象String.Class
			 * 
			 * 如fieldName:=============name; =====set方法名就是setName public void setName(String
			 * name) { this.name = name ; }
			 */
			String methoName = "set" + fieldName.substring(0, 1).toUpperCase()
					+ fieldName.substring(1, fieldName.length());

			/* 获取方法 */
			try
			{
				Method method = cla.getMethod(methoName, fieldTemp.getType());
				// System.out.println(fieldTemp.getName() + "===反射属性===" + val + "===" +
				// fieldTemp.getType() + method);

				/*
				 * 调用方法赋值 参数1:是一个Java对象 参数2:实参的值
				 */
				/* Byte出了问题 */
				if ("byte".equalsIgnoreCase(fieldTemp.getType().getSimpleName()))
				{
					method.invoke(obj, Byte.parseByte(val + ""));
				} else
				{
					method.invoke(obj, val);
				}
			} catch (Exception e)
			{
				//e.printStackTrace();
			}

		}
		return obj;
	}

	
}
